// Copyright (c) 2006  John Abbott
// This file is part of the CoCoALib suite of examples.
// You are free to use any part of this example in your own programs.

#include "CoCoA/library.H"
using namespace CoCoA;
using namespace std;

void program()
{
  GlobalManager CoCoAFoundations;
  // Put your code here.
   //DenseUPolyRing R = NewPolyRing_DUP(RingZ(), symbol("x"));
   symbol x("x"), y("y"), z("z");
   vector<symbol> indets;
   indets.push_back(x);
   indets.push_back(y);
   indets.push_back(z);
   DenseUPolyRing Rx = NewPolyRing_DUP(RingZ(), symbol("x"));
   PPOrdering ppo = NewLexOrdering(3);
   cout << ppo << endl;
   PPMonoid ppm = NewPPMonoid(indets,ppo);
   cout << ppm << endl;
   SparsePolyRing Qx = NewPolyRing(RingQ(),ppm);
   cout << Qx << endl;
   vector<RingElem> vars = CoCoA::indets(Qx); // have to use CoCoA::
   RingElem p(Qx), vx=vars[0], vy=vars[1],vz=vars[2];
   p= p+4*power(vz,2)*power(vy,2)+2*power(vx,2)*power(vz,2)+3*power(vx,2)*power(vy,2)+1;
   cout << p << endl;
   vector<int long> expv2;
   for (SparsePolyIter i=BeginIter(p); i!=EndIter(p); i++) {
		   cout << "pp: " << PP(i) <<"\t wdeg(pp): "<< CoCoA::wdeg(PP(i))<< "\t" << "coeff: " << coeff(i) << endl;
		   exponents(expv2,PP(i));
		   cout << "[ " ;
		   for (size_t idx=0; idx< expv2.size(); idx++)
   		      cout << expv2[idx]<< " ";
		   cout << "]" << endl;
		  // p+=PP(i);
   }
   
   cout << deg(p) << endl;


   SparsePolyRing Q3 = NewPolyRing(RingQ(),3);
   vector<long int> expv(3);
   expv[2]=3;
   // degree expv(3);
   expv[0]=3;
   expv[1]=2;
   // RingElem q3(monomial(Q3,3+q3,expv)); // segmentation fault
   RingElem q3(monomial(Q3,3,expv));
   cout <<"Q3: " << Q3 << endl;
   cout << q3 << endl;
   cout << wdeg(q3) << endl;
   q3 += indet(Q3,2) * power(indet(Q3,2),12);
   cout << q3 << endl;
   // q3 = q3+

   cout << wdeg(q3) << endl;


}
// Use main() to handle any uncaught exceptions and warn the user about them.
int main()
{
  try
  {
    program();
    return 0;
  }
  catch (const CoCoA::ErrorInfo& err)
  {
    cerr << "***ERROR***  UNCAUGHT CoCoA error";
    ANNOUNCE(cerr, err);
  }
  catch (const std::exception& exc)
  {
    cerr << "***ERROR***  UNCAUGHT std::exception: " << exc.what() << endl;
  }
  catch(...)
  {
    cerr << "***ERROR***  UNCAUGHT UNKNOWN EXCEPTION" << endl;
  }
  return 1;
}
